#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <vector>
using namespace std;

typedef void(*pf)();
vector<pf> arrpf;

void func1(){
  cout << "父进程临时任务1" << endl;
}

void func2(){
  cout << "父进程临时任务2" << endl;
}

//想让父进程在等待子进程过程中执行临时任务，只需要在Load中注册任务即可。
void Load(){ //加载回调函数
  arrpf.push_back(func1); 
  arrpf.push_back(func2); 
}

int main(){
  pid_t id = fork();
  if(id < 0)
  {
    perror("fork");
    exit(10);
  }
  else if(id == 0)
  {
    int cnt = 3;
    while(cnt--){
      cout << "I'm child process!";
      cout << " pid:" << getpid();
      cout << " ppid:" << getppid();
      cout << "  " << cnt+1 << endl;
      sleep(1);
      //cnt/=0;
      //int *p = NULL;
      //*p = 100;
    }
    exit(122);
  }
  else{
    //父进程等待回收子进程
    //wait
    //sleep(5);
    //pid_t ret = wait(nullptr); 
    //if(ret > 0)
    //{
    //  cout << "等待子进程成功！ret:" << ret << endl;
    //}
    
    //waitpid
    //sleep(5);
    //int status = 0;
    //pid_t ret = waitpid(id, &status, 0); 
    //if(ret > 0)
    //{
    //  cout << "等待子进程成功！ret:" << ret;
    //  cout << " status:" << status << endl;
    //  //cout << " exit_code:" << ((status>>8)&0xFF) << endl;
    //}
    
    //sleep(5);
    //int status = 0;
    //pid_t ret = waitpid(id, &status, 0); 
    //if(ret > 0)
    //{
    //  cout << "等待子进程成功！ret:" << ret;
    //  cout << " SIGNUM:" << (status&0x7F);
    //  cout << " ExitCode:" << ((status>>8)&0xFF) << endl;
    //}

    //sleep(5);
    //int status = 0;
    //pid_t ret = waitpid(id, &status, 0); 
    //if(WIFEXITED(status)) //判断子进程是否正常退出
    //{
    //  cout << "子进程正常退出！child_pid:" << ret;
    //  cout << " exit_code:" << WEXITSTATUS(status) << endl; //查看子进程的退出码
    //}
    //else{
    //  cout << "子进程运行崩溃！child_pid:" << ret;
    //  cout << " exit_signal:" << (status&0x7F) << endl; //查看子进程的退出信号
    //}

    int status = 0;
    while(1)
    {
      pid_t ret = waitpid(-1, &status, WNOHANG); //以非阻塞方式等待 
      if(ret > 0) //子进程退出
      {
        if(WIFEXITED(status)) //判断子进程是否正常退出
        {
          cout << "子进程正常退出！child_pid:" << ret;
          cout << " exit_code:" << WEXITSTATUS(status) << endl; //查看子进程的退出码
        }
        else{
          cout << "子进程运行崩溃！child_pid:" << ret;
          cout << " exit_signal:" << (status&0x7F) << endl; //查看子进程的退出信号
        }
        break;
      }
      else if(ret == 0) //子进程未退出
      {
        cout << "子进程正在运行..." << endl;
        
        if(arrpf.empty()) Load();
        for(auto iter : arrpf)
        {
          //等待子进程的过程中执行其他任务
          iter(); 
        }
      }
      else{ //等待子进程失败
        cout << "等待子进程失败！" << endl;
        break;
      }
      sleep(1);
    }

    while(1){
      cout << "I'm father process!";
      cout << " pid:" << getpid();
      cout << " ppid:" << getppid() << endl;
      sleep(1);
    }
  }
}

